home *** CD-ROM | disk | FTP | other *** search
- //
- // MiscDateView.m -- a view for dealing with input and display of dates
- // Written by Hugh Ashton, Copyright (c) 1994 by Hugh Ashton.
- // Version 1.0 All rights reserved.
- // This notice may not be removed from this source code.
- //
- // This object is included in the MiscKit by permission from the author
- // and its use is governed by the MiscKit license, found in the file
- // "LICENSE.rtf" in the MiscKit distribution. Please refer to that file
- // for a list of all applicable permissions and restrictions.
- //
-
- #include <time.h>
- #include <libc.h>
- #include <strings.h>
- #import "MiscDateView.h"
-
- #define CURRENT_VERSION 1
-
- id BundleForStrings = nil;
-
- #define MONDAY NXLocalizedStringFromTableInBundle (NULL,BundleForStrings,"Monday",NULL,zeroth day of week)
- #define TUESDAY NXLocalizedStringFromTableInBundle (NULL,BundleForStrings,"Tuesday",NULL,first day of week)
- #define WEDNESDAY NXLocalizedStringFromTableInBundle (NULL,BundleForStrings,"Wednesday",NULL,second day of week)
- #define THURSDAY NXLocalizedStringFromTableInBundle (NULL,BundleForStrings,"Thursday",NULL,third day of week)
- #define FRIDAY NXLocalizedStringFromTableInBundle (NULL,BundleForStrings,"Fri",NULL,fourth day of week)
- #define SATURDAY NXLocalizedStringFromTableInBundle (NULL,BundleForStrings,"Sat",NULL,fifth day of week)
- #define SUNDAY NXLocalizedStringFromTableInBundle (NULL,BundleForStrings,"Sun",NULL,sixth day of week)
- #define DATE_ERROR NXLocalizedStringFromTableInBundle (NULL,BundleForStrings,"Date entry error",NULL,error in date entry)
-
- @implementation MiscDateView
-
- + initialize
- {
- if ( self == [MiscDateView class] )
- [MiscDateView setVersion:CURRENT_VERSION];
-
- return self;
- }
-
- - decDay:sender
- {
- int mm;
-
- if(strlen([day stringValue])>0)
- {
- [day setIntValue:[day intValue]-1];
- }
- if([day intValue]<1)
- {
- [month setIntValue:[month intValue]-1];
- if([month intValue]<1)
- {
- [month setIntValue:12];
- [year setIntValue:[year intValue]-1];
- }
- mm=[month intValue];
- if(mm==4 || mm==6 || mm==9 || mm==11)
- /*
- 30 days hath September...
- */ {
- [day setIntValue:30];
- [self outputDOW:[self whatDayIs:[day intValue] :[month intValue] : [year intValue]]];
- return self;
- }
- if(mm==2)
- {
- if([self isItaLeapYear:[year intValue]])
- /*
- leap year
- */
- {
- [day setIntValue:29];
- }
- else
- {
- [day setIntValue:28];
- }
- [self outputDOW:[self whatDayIs:[day intValue] :[month intValue] : [year intValue]]];
- return self;
- }
- [day setIntValue:31];
- }
- [self outputDOW:[self whatDayIs:[day intValue] :[month intValue] : [year intValue]]];
- [self isDateValid:self];
-
- return self;
- }
-
- - decMonth:sender
- {
- if(strlen([month stringValue])>0)
- {
- [month setIntValue:[month intValue]-1];
- }
- if([month intValue]<1)
- {
- [month setIntValue:12];
- [year setIntValue:[year intValue]-1];
- }
- [self outputDOW:[self whatDayIs:[day intValue] :[month intValue] : [year intValue]]];
- [self isDateValid:self];
- return self;
- }
-
- - outputDOW:(unsigned int)number
- {
- number=number%7;
-
- if(number==0)
- {
- [dow setStringValue:MONDAY];
- return self;
- }
- if(number==1)
- {
- [dow setStringValue:TUESDAY];
- return self;
- }
- if(number==2)
- {
- [dow setStringValue:WEDNESDAY];
- return self;
- }
- if(number==3)
- {
- [dow setStringValue:THURSDAY];
- return self;
- }
- if(number==4)
- {
- [dow setStringValue:FRIDAY];
- return self;
- }
- if(number==5)
- {
- [dow setStringValue:SATURDAY];
- return self;
- }
- if(number==6)
- {
- [dow setStringValue:SUNDAY];
- return self;
- }
- return self;
- }
-
- - decYear:sender
- {
- if(strlen([year stringValue])>0)
- {
- [year setIntValue:[year intValue]-1];
- }
- [self outputDOW:[self whatDayIs:[day intValue] :[month intValue] : [year intValue]]];
- [self isDateValid:self];
- return self;
- }
-
- - checkDay:sender
- {
- if((strlen([day stringValue])==0) || (strlen([month stringValue])==0) || (strlen([year stringValue])==0))
- {
- [dow setStringValue:"XXX"];
- return self;
- }
- [self outputDOW:[self whatDayIs:[day intValue] :[month intValue] : [year intValue]]];
- [self isDateValid:self];
- return self;
- }
- - (unsigned int)whatDayIs:(int)theDay :(int)theMonth :(int)theYear
- /*
- we take 1 January 1901 as our base
- Mon=0, Tue=1, etc
- */
- {
- unsigned int i;
- unsigned int current_count;
- current_count=1;
- /*
- as it happens, 1/1/1901 was a Tuesday
- */
- if(theYear<1901)
- {
- return 00;
- }
- for(i=1901;i<theYear;i++)
- {
- if([self isItaLeapYear:i])
- {
- current_count=(current_count+=366);
- }
- else
- {
- current_count=(current_count+=365);
- }
- }
- for(i=1;i<theMonth;i++)
- {
- if((i==4) || (i==6) || (i==9) || (i==11))
- {
- current_count+=30;
- }
- if((i==2) && ([self isItaLeapYear:theYear]))
- {
- current_count+=29;
- }
- if((i==2) && (![self isItaLeapYear:theYear]))
- {
- current_count+=28;
- }
- if((i==1) || (i==3) || (i==5) || (i==7) || (i==8) || (i==10) || (i==12))
- {
- current_count+=31;
- }
- }
- for(i=1;i<theDay;i++)
- {
- current_count+=1;
- }
-
- /*
- fencepost error, hence this kludge
- current_count=current_count-1;
- */
- return current_count;
- }
- - (BOOL)isItaLeapYear:(int)theYear
- {
- // Fix from Rod Ragner:
- return ((!(theYear % 4) && (theYear % 200)) ? YES : NO);
- // old way is incorrect:
- // if((theYear/4.0)==(theYear/4))
- // {
- // return YES;
- // }
- // else
- // {
- // return NO;
- // }
- }
- - getTodaysDate:sender
- {
- long currenttime;
- char dateString[60]="";
- int dd;
- int mm=0;
- char mmStr[4]="";
- int yyyy;
- char dowStr[4]="";
- char timeString[20]="";
-
- currenttime = time(0L);
- strcpy(dateString,ctime(¤ttime));
-
- sscanf(dateString,"%s %s %d %s %d",dowStr,mmStr,&dd,timeString,&yyyy);
- [dow setStringValue:dowStr];
- [year setIntValue:yyyy];
- [day setIntValue:dd];
- if(strcmp(mmStr,"Jan")==0)
- {
- mm=1;
- }
- if((strcmp(mmStr,"Feb"))==0)
- {
- mm=2;
- }
- if((strcmp(mmStr,"Mar"))==0)
- {
- mm=3;
- }
- if((strcmp(mmStr,"Apr"))==0)
- {
- mm=4;
- }
- if((strcmp(mmStr,"May"))==0)
- {
- mm=5;
- }
- if((strcmp(mmStr,"Jun"))==0)
- {
- mm=6;
- }
- if((strcmp(mmStr,"Jul"))==0)
- {
- mm=7;
- }
- if((strcmp(mmStr,"Aug"))==0)
- {
- mm=8;
- }
- if((strcmp(mmStr,"Sep"))==0)
- {
- mm=9;
- }
- if((strcmp(mmStr,"Oct"))==0)
- {
- mm=10;
- }
- if((strcmp(mmStr,"Nov"))==0)
- {
- mm=11;
- }
- if((strcmp(mmStr,"Dec"))==0)
- {
- mm=12;
- }
- [month setIntValue:mm];
- return self;
- }
-
- - incDay:sender
- {
- int mm=0;
-
- mm=[month intValue];
-
- if(strlen([day stringValue])>0)
- {
- [day setIntValue:[day intValue]+1];
- }
- if((mm==4 || mm==6 || mm==9 || mm==11) && [day intValue]>30)
- {
- [month setIntValue:[month intValue]+1];
- [day setIntValue:1];
- [self outputDOW:[self whatDayIs:[day intValue] :[month intValue] : [year intValue]]];
- return self;
- }
- if((mm==2) && ([day intValue]>28) && (![self isItaLeapYear:[year intValue]]))
- {
- [month setIntValue:3];
- [day setIntValue:1];
- [self outputDOW:[self whatDayIs:[day intValue] :[month intValue] : [year intValue]]];
- return self;
- }
- if((mm==2) && ([day intValue]>29) && ([self isItaLeapYear:[year intValue]]))
- {
- [month setIntValue:3];
- [day setIntValue:1];
- [self outputDOW:[self whatDayIs:[day intValue] :[month intValue] : [year intValue]]];
- return self;
- }
-
- if([day intValue]>31)
- {
- [month setIntValue:[month intValue]+1];
- [day setIntValue:1];
- if([month intValue]>12)
- {
- [month setIntValue:1];
- [year setIntValue:[year intValue]+1];
- }
- }
- [self outputDOW:[self whatDayIs:[day intValue] :[month intValue] : [year intValue]]];
- [self isDateValid:self];
- return self;
- }
-
- - incMonth:sender
- {
- if(strlen([month stringValue])>0)
- {
- [month setIntValue:[month intValue]+1];
- }
- if([month intValue]>12)
- {
- [month setIntValue:1];
- [year setIntValue:[year intValue]+1];
- }
- [self outputDOW:[self whatDayIs:[day intValue] :[month intValue] : [year intValue]]];
- [self isDateValid:self];
- return self;
- }
-
- - incYear:sender
- {
- if(strlen([year stringValue])>0)
- {
- [year setIntValue:[year intValue]+1];
- }
- [self outputDOW:[self whatDayIs:[day intValue] :[month intValue] : [year intValue]]];
- [self isDateValid:self];
- return self;
- }
-
- - (BOOL)isDateValid:sender
- {
- if(([year intValue]>2050) || ([year intValue]<1901))
- {
- NXRunAlertPanel(DATE_ERROR,"Year is outside range 1901 to 2050","OK",NULL,NULL);
- [year selectText:self];
- [dow setStringValue:"XXX"];
- return NO;
- }
- if(([month intValue]>12) || ([month intValue]<1))
- {
- NXRunAlertPanel(DATE_ERROR,"Month is outside range 1 to 12","OK",NULL,NULL);
- [month selectText:self];
- [dow setStringValue:"XXX"];
- return NO;
- }
- if(([day intValue]<1) || ([day intValue]>31))
- {
- NXRunAlertPanel(DATE_ERROR,"Day is outside range 1 to 31","OK",NULL,NULL);
- [day selectText:self];
- [dow setStringValue:"XXX"];
- return NO;
- }
- if(([month intValue]==4 || [month intValue]==6 || [month intValue]==9 || [month intValue]==11) && [day intValue]>30)
- {
- NXRunAlertPanel(DATE_ERROR,"Day is outside range for this month (1 to 30)","OK",NULL,NULL);
- [day selectText:self];
- [dow setStringValue:"XXX"];
- return NO;
- }
- if([month intValue]==2 && ![self isItaLeapYear:[year intValue]] && [day intValue]>28)
- {
- NXRunAlertPanel(DATE_ERROR,"Day is outside range for this month (1 to 28). %d is not a leap year","OK",NULL,NULL,[year intValue]);
- [day selectText:self];
- [dow setStringValue:"XXX"];
- return NO;
- }
- if([month intValue]==2 && [self isItaLeapYear:[year intValue]] && [day intValue]>29)
- {
- NXRunAlertPanel(DATE_ERROR,"Day is outside range for this month (1 to 29). %d is a leap year","OK",NULL,NULL,[year intValue]);
- [day selectText:self];
- [dow setStringValue:"XXX"];
- return NO;
- }
-
-
- return YES;
- }
-
- - initFrame:(const NXRect *)frameRect
- {
- [super initFrame:frameRect];
-
- return self;
- }
-
- - drawSelf:(const NXRect *)rects :(int)rectCount
- {
- PSsetgray(NX_LTGRAY);
- NXRectFill(&bounds);
- return self;
- }
-
- - read:(NXTypedStream *)stream
- {
- int version;
- [super read:stream];
- version = NXTypedStreamClassVersion(stream, "MiscDateView");
- if ( version == CURRENT_VERSION ) {
- day = NXReadObject(stream);
- dayDown = NXReadObject(stream);
- dayUp = NXReadObject(stream);
- dow = NXReadObject(stream);
- month = NXReadObject(stream);
- monthDown = NXReadObject(stream);
- monthUp = NXReadObject(stream);
- year = NXReadObject(stream);
- yearDown = NXReadObject(stream);
- yearUp = NXReadObject(stream);
- } else {
- [self error:"Unknown version!"];
- }
- return self;
- }
-
- - write:(NXTypedStream *)stream
- {
- [super write:stream];
- NXWriteObject(stream, day);
- NXWriteObject(stream, dayDown);
- NXWriteObject(stream, dayUp);
- NXWriteObject(stream, dow);
- NXWriteObject(stream, month);
- NXWriteObject(stream, monthDown);
- NXWriteObject(stream, monthUp);
- NXWriteObject(stream, year);
- NXWriteObject(stream, yearDown);
- NXWriteObject(stream, yearUp);
- return self;
- }
-
-
- - (int)getDay:sender
- {
- return [day intValue];
- }
-
- - (int)getMonth:sender
- {
- return [month intValue];
- }
-
- - (int)getYear:sender
- {
- return [year intValue];
- }
-
- - day:sender
- {
- return day;
- }
-
- - month:sender
- {
- return month;
- }
-
- - year:sender
- {
- return year;
- }
- @end
-